package com.JUC.cha04.sec01;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 公平锁：是指多个线程按照申请锁的顺序来获取锁，排队买饭，抢票之类的    Lock lock = new ReentrantLock(true);
 * 非公平锁：是指多个线程获取锁的顺序并不是按照申请锁的顺序，可能后申请的线程先获取锁，在高并发下可能造成优先级反转或者饥饿的状态（某个线程一直得不到锁）
 * Lock lock = new ReentrantLock(false);        Lock lock = new ReentrantLock();
 *
 * 为什么会有公平锁和非公平锁的设计？为什么默认非公平？什么时候用公平？什么时候用非公平？
 *
 * 非公平锁能更充分的利用CPU的时间片，尽量减少CPU空闲状态时间
 * 使用多线程很重要的考虑是线程切换的开销，当采用非公平锁时，当一个线程请求锁，释放锁，刚释放锁的线程在此刻再次获取锁的概率变得非常大，所以减少了线程的开销
 * 考虑性能用非公平
 * 考虑公平用公平锁
 */
public class Ticker {

    private Integer number = 50;
    Lock lock = new ReentrantLock(true);

    public void sale() {

        lock.lock();
        try
        {
            if (number > 0)
            {
                System.out.println(Thread.currentThread().getName() + "卖出第：\t" + (number--) + "\t 还剩下：" + number);
            }

        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        Ticker ticker = new Ticker();
        new Thread(() -> { for (int i = 0; i < 55; i++) { ticker.sale(); } }, "a").start();
        new Thread(() -> { for (int i = 0; i < 55; i++) { ticker.sale(); } }, "b").start();
        new Thread(() -> { for (int i = 0; i < 55; i++) { ticker.sale(); } }, "c").start();
    }
}
